#ifndef HEADER_H
#define HEADER_H
using namespace std;
#include <iostream>

template <typename T>
class Matrix
  {
  private:
    int row,col;
    T *matrix_element;
  public:
    Matrix(){}//multiply 2 matrices
    Matrix operator*(const Matrix&B)
      {static Matrix C;
      if(col!=B.row)
          cout <<"Invalid input";
      C.row=row;
      C.col=B.col;
    C.matrix_element=new T [C.row*C.col];
      for(int i=0;i<C.row;i++)
        for(int j=0;j<C.col;j++)
          for(int k=0;k<col;k++)
     C.matrix_element[i*B.col+j]+=matrix_element[i*col+k]*B.matrix_element[k*B.col+j];
      return C;
      }
          
    ~Matrix()//destructor
      {
       if(matrix_element!= NULL)
	 delete [] matrix_element;
      }
    Matrix(int n_row,int n_col)
      {
    row=n_row;
        col=n_col;
    matrix_element = new T [row*col];
      }
    bool is_square()//determine the matrix is a squarematrix or not
    { if(col==row)
    return true;
      else
    return false;
    }
    T get_matrix_element(const int _i, const int _j);
    T*get_element(){
      return matrix_element;
    }
    void set_matrix_element(const int _i,const int _j,const T _v);
      T getcol(){
          return col;
      }
      T getrow(){
	return row;
      }
  };

template <typename T>
 T Matrix<T>::get_matrix_element(int _i,int _j)
 {
   return matrix_element[_i * col + _j];
 };

template <typename T>
 void Matrix<T>::set_matrix_element(int _i,int _j,T _v)
 {matrix_element[_i * col +_j]=_v;
 };

template <typename T>
  class ColVector : public Matrix<T>
{
 public:
    ColVector(int n_row):Matrix<T>(n_row,1)
    {
    }
  T getrow()//use this to know how many rows this Colvector has
  {
    return Matrix<T>::getrow();
  }
   T* get_ColVector_element()
   {return Matrix<T>::get_element();
   }
   T operator*(const ColVector &B)//multiplication for vectors
    {T sum=0;
      for(int i=0;i<Matrix<T>::row;i++)
    sum+=Matrix<T>::get_matrix_element[i]*B.get_matrix_element[i];
      return sum;
    };
};

template <typename T>
class RowVector : public Matrix<T>
 {
 public:
     RowVector(int n_col):Matrix<T>(1,n_col)
     {
     }
     T getcol(){
         return Matrix<T>::getcol();
     }
     T* get_RowVector_element()
     {return Matrix<T>::get_element();
      }
  T operator*( RowVector &B)
    {T sum=0;
      for(int i=0;i<B.getcol();i++)
    sum+=get_RowVector_element()[i]*B.get_RowVector_element()[i];
      return sum;
    };
 };
#endif 
